package com.ruoyi.prt.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.prt.domain.PrtOrg;
import com.ruoyi.prt.domain.vo.PrtCouponVO;
import com.ruoyi.prt.mapper.PrtOrgMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.prt.mapper.PrtCouponMapper;
import com.ruoyi.prt.domain.PrtCoupon;
import com.ruoyi.prt.service.IPrtCouponService;

/**
 * 优惠券Service业务层处理
 *
 * @author xiaobo Yan
 * @date 2021-03-31
 */
@Service
public class PrtCouponServiceImpl implements IPrtCouponService {
    @Autowired
    private PrtCouponMapper prtCouponMapper;

    @Autowired
    private PrtOrgMapper prtOrgMapper;

    /**
     * 查询优惠券
     *
     * @param couponId 优惠券ID
     * @return 优惠券
     */
    @Override
    public PrtCoupon selectPrtCouponById(String couponId) {
        return prtCouponMapper.selectPrtCouponById(couponId);
    }

    /**
     * 查询优惠券列表
     *
     * @param prtCoupon 优惠券
     * @return 优惠券
     */
    @Override
    public List<PrtCoupon> selectPrtCouponList(PrtCoupon prtCoupon) {
        return prtCouponMapper.selectPrtCouponList(prtCoupon);
    }

    /**
     * 新增优惠券
     *
     * @param prtCoupon 优惠券
     * @return 结果
     */
    @Override
    public int insertPrtCoupon(PrtCoupon prtCoupon) {
        return prtCouponMapper.insertPrtCoupon(prtCoupon);
    }

    /**
     * 修改优惠券
     *
     * @param prtCoupon 优惠券
     * @return 结果
     */
    @Override
    public int updatePrtCoupon(PrtCoupon prtCoupon) {
        return prtCouponMapper.updatePrtCoupon(prtCoupon);
    }

    /**
     * 批量删除优惠券
     *
     * @param couponIds 需要删除的优惠券ID
     * @return 结果
     */
    @Override
    public int deletePrtCouponByIds(String[] couponIds) {
        return prtCouponMapper.deletePrtCouponByIds(couponIds);
    }

    /**
     * 删除优惠券信息
     *
     * @param couponId 优惠券ID
     * @return 结果
     */
    @Override
    public int deletePrtCouponById(String couponId) {
        return prtCouponMapper.deletePrtCouponById(couponId);
    }

    @Override
    public AjaxResult calcDiscountedPrice(BigDecimal originalPrice, String couponId, String orgId, Long userId, String couponType) {
        PrtCoupon prtCoupon = prtCouponMapper.selectPrtCouponById(couponId);
        PrtCouponVO prtCouponVO = new PrtCouponVO();
        prtCouponVO.setOriginalPrice(originalPrice);
        prtCouponVO.setPriceType(couponType);
        prtCouponVO.setIsUsed(false);
        prtCouponVO.setIsExist(prtCoupon == null || !userId.equals(prtCoupon.getRecipient()));
        if (prtCoupon == null || !userId.equals(prtCoupon.getRecipient())) {
            return AjaxResult.error(MessageUtils.message("prt.coupon.exist"), prtCouponVO);
        }
        BeanUtils.copyProperties(prtCoupon, prtCouponVO);
        if (prtCoupon.getIsUse() == 1) {
            return AjaxResult.error(MessageUtils.message("prt.coupon.used"), prtCouponVO);
        }
        Date expireTime = prtCoupon.getExpireTime();
        prtCouponVO.setIsExpire(expireTime != null && expireTime.before(new Date()));
        //优惠券过期
        if (prtCouponVO.getIsExpire()) {
            return AjaxResult.error(MessageUtils.message("prt.coupon.expire"), prtCouponVO);
        }
        prtCouponVO.setIsOrg(true);
        //只能在某个组织使用
        if (StringUtils.isNotEmpty(prtCoupon.getOrgId())) {
            PrtOrg org = prtOrgMapper.selectPrtOrgById(orgId);
            prtCouponVO.setIsOrg(prtCoupon.getOrgId().equals(orgId));
            prtCouponVO.setOrgName(org.getOrgName());
            if (!prtCouponVO.getIsOrg()) {
                return AjaxResult.error(MessageUtils.message("prt.coupon.match.org", org.getOrgName()), prtCouponVO);
            }
        }
        prtCouponVO.setIsType(StringUtils.isEmpty(prtCoupon.getCouponType())
                || couponType.equals(prtCoupon.getCouponType()));
        //匹配使用类型
        if (!prtCouponVO.getIsType()) {
            return AjaxResult.error(MessageUtils.message("prt.coupon.match.type", couponType), prtCouponVO);
        }
        //使用门槛
        BigDecimal thresholdPrice = prtCoupon.getThresholdPrice();
        prtCouponVO.setIsThreshold(thresholdPrice == null || thresholdPrice.compareTo(BigDecimal.ZERO) <= 0
                || originalPrice.compareTo(thresholdPrice) >= 0);
        if (!prtCouponVO.getIsThreshold()) {
            return AjaxResult.error(MessageUtils.message("prt.coupon.match.threshold"
                    , Objects.requireNonNull(thresholdPrice).toString()), prtCouponVO);
        }
        //满减和折扣取最大优惠（如果通过存在）
        BigDecimal fullReduction = BigDecimal.ZERO;
        BigDecimal discount = BigDecimal.ZERO;
        BigDecimal discountRatio = prtCoupon.getDiscountRatio();
        if (discountRatio != null && discountRatio.compareTo(BigDecimal.ZERO) > 0) {
            fullReduction = discountRatio.multiply(originalPrice);
        }
        BigDecimal couponPrice = prtCoupon.getCouponPrice();
        if (couponPrice != null && couponPrice.compareTo(BigDecimal.ZERO) > 0) {
            discount = couponPrice;
        }
        BigDecimal price = fullReduction.max(discount);
        BigDecimal maxCouponPrice = prtCoupon.getMaxCouponPrice();
        //是否自动选择最佳优惠方式
        prtCouponVO.setIsChoice(fullReduction.compareTo(BigDecimal.ZERO) > 0 && discount.compareTo(BigDecimal.ZERO) > 0);
        //优惠类型
        prtCouponVO.setOfferType((fullReduction.compareTo(discount) > 0) ? MessageUtils.message("prt.coupon.text.discount") : MessageUtils.message("prt.coupon.text.fullReduction"));
        //达到最大优惠
        prtCouponVO.setIsMax(maxCouponPrice != null && maxCouponPrice.compareTo(price) >= 0);
        if (prtCouponVO.getIsMax()) {
            price = maxCouponPrice;
        }
        prtCouponVO.setFullReduction(fullReduction);
        prtCouponVO.setDiscount(discount);
        prtCouponVO.setPrice(price);
        prtCouponVO.setPayPrice(originalPrice.subtract(price));
        prtCouponVO.setIsUsed(true);
        return AjaxResult.success(prtCouponVO);
    }

}
